// Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using Data = PfRep.DataEntities;

using PfRep.Library;
using System.Collections;
using System.Data.SqlClient;
using System.Diagnostics;
using PfRep.Common;
using System.Threading;

namespace PfRep.Console
{
    public partial class ManageDataSources : Form
    {
        /// <summary>
        /// Indicates whether the user has cancelled the window
        /// </summary>
        public bool UserCancelled = false;
        
        /// <summary>
        /// The selected public folder tree ID
        /// </summary>
        public Data.FolderTree SelectedFolderTree;
        
        /// <summary>
        /// The selected content statistic ID
        /// </summary>
        public int SelectedContentStatisticId = 0;

        /// <summary>
        /// Fills up the folder structure with data
        /// </summary>
        private void FillUpFolderTree()
        {
            FolderTrees.Items.Clear();
            FolderTrees.Items.AddRange(Statistics.GetFolderTrees().ToArray());

            FolderTrees.DisplayMember = "Name";
            FolderTrees.ValueMember = "ID";
        }

        /// <summary>
        /// Fills up the content statistics combo based on the folder structure combo's selected
        /// item
        /// </summary>
        private void FillUpContentStatistics()
        {
            ContentStatistics.SelectedItem = null;

            ContentStatistics.Items.Clear();
            ContentStatistics.Items.AddRange(
                Statistics.GetContentStatistics(SelectedFolderTree.ID).ToArray());

            ContentStatistics.DisplayMember = "Value";
            ContentStatistics.ValueMember = "Key";

            // If at least one item in the tree list, we select the 1st one
            if (ContentStatistics.Items.Count > 0)
                ContentStatistics.SelectedIndex = 0;
        }

        /// <summary>
        /// Initializes the form
        /// </summary>
        public ManageDataSources()
        {
            // Initializes the form controls
            InitializeComponent();
        }

        /// <summary>
        /// Enables/disables the OK button, based whether there are selected values in
        /// both comboboxes
        /// </summary>
        private void SetOkButton()
        {
            // If both options are selected, the OK button gets enabled, otherwise, disabled
            if (SelectedFolderTree.ID > 0 && !string.IsNullOrEmpty(FolderTrees.Text))
                cmdOK.Enabled = true;
            else
                cmdOK.Enabled = false;

            // If the public folder tree item is selected, activate the Create button
            //  next to the content statistics combobox
            if (SelectedFolderTree.ID > 0 && !string.IsNullOrEmpty(FolderTrees.Text))
                cmdCreateFolderStatistics.Enabled = true;
        }

        /// <summary>
        /// OK button click
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmdOK_Click(object sender, EventArgs e)
        {
            this.Hide();
        }

        /// <summary>
        /// Updates the content statistics combo
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FolderTrees_SelectedIndexChanged(object sender, EventArgs e)
        {
            // If there's no item selected in the tree structure combo, exiting
            if (FolderTrees.SelectedItem == null)
            {
                SelectedFolderTree = new Data.FolderTree(0, "", "");

                return;
            }

            // Get the selected ID
            SelectedFolderTree = (Data.FolderTree)FolderTrees.SelectedItem;

            // Fill up the content statistics combo
            FillUpContentStatistics();

            // Enable/disable the OK button
            SetOkButton();
        }

        /// <summary>
        /// Enables/disables the OK button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ContentStatistics_SelectedIndexChanged(object sender, EventArgs e)
        {
            // If there's no item selected in the tree structure combo, exiting
            if (ContentStatistics.SelectedItem == null)
            {
                SelectedContentStatisticId = 0;
                return;
            }

            // Get the selected ID
            SelectedContentStatisticId = ((KeyValuePair<int, string>)ContentStatistics.SelectedItem).Key;

            // Enable/disable the OK button
            SetOkButton();
        }

        /// <summary>
        /// Opens the Create Folder Tree window
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmdCreateFolderTree_Click(object sender, EventArgs e)
        {
            // Open the new folder index window
            IndexFolderTree indexFolderTree = new IndexFolderTree();
            indexFolderTree.ShowDialog(this);

            // Fill up with the new values
            FillUpFolderTree();

            // Select the new folder tree that just created
            foreach (Data.FolderTree folderTreeItem in FolderTrees.Items)
            {
                if (string.Compare(folderTreeItem.Name,
                    indexFolderTree.NewlyCreatedFolderTreeName, true) == 0)
                {
                    FolderTrees.SelectedItem = folderTreeItem;
                    break;
                }
            }
            
            // Refresh the tree combo if there's any change in it
            if (!indexFolderTree.UserCancelled)
            {
                // Asks the user whether he/she wants to start content indexing
                if (MessageBox.Show(
                    "Do you want to start content indexing for the folder tree you just traversed? " +
                    "(this is the feature that shows folder usage/statistics, without this you'll see " +
                    "only the folder tree of your Exchange Server)",
                    "PfRep", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    // Open the new content statistics index window
                    IndexContentStatistics indexStatistics = new IndexContentStatistics();

                    // Set the parent folder and unattended values
                    indexStatistics.PublicFolderTree = SelectedFolderTree;
                    indexStatistics.Username = indexFolderTree.Username;
                    indexStatistics.Password = indexFolderTree.Password;
                    indexStatistics.StartAutomatically = true;

                    // Show the dialog
                    indexStatistics.ShowDialog(this);

                    // Refresh the content stat combo if there's any change in it
                    if (!indexStatistics.UserCancelled)
                    {
                        // Fill up with the new values
                        FillUpContentStatistics();

                        // Select the new one
                        foreach (KeyValuePair<int, string> contentStatItem in ContentStatistics.Items)
                        {
                            if (string.Compare(contentStatItem.Value,
                                indexStatistics.NewlyCreatedContentStatisticsName, true) == 0)
                            {
                                ContentStatistics.SelectedItem = contentStatItem;
                                break;
                            }
                        }
                    }

                }
            }
        }

        /// <summary>
        /// Opens the Create Folder Statistics window
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmdCreateFolderStatistics_Click(object sender, EventArgs e)
        {
            // Open the new content statistics index window
            IndexContentStatistics indexStatistics = new IndexContentStatistics();

            // Set the parent folder
            indexStatistics.PublicFolderTree = SelectedFolderTree;
            
            // Show the dialog
            indexStatistics.ShowDialog(this);

            // Fill up with the new values
            FillUpContentStatistics();

            // Select the new one
            foreach (KeyValuePair<int, string> contentStatItem in ContentStatistics.Items)
            {
                if (string.Compare(contentStatItem.Value,
                    indexStatistics.NewlyCreatedContentStatisticsName, true) == 0)
                {
                    ContentStatistics.SelectedItem = contentStatItem;
                    break;
                }
            }
        }

        /// <summary>
        /// Cancel button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmdCancel_Click(object sender, EventArgs e)
        {
            UserCancelled = true;
        }

        /// <summary>
        /// Pops up the options dialog
        /// </summary>
        /// <returns>Cancel if the dialog was cancelled</returns>
        private bool PopupOptionsDialog()
        {
            Options optionsDialog = new Options();
            optionsDialog.DisplayMode = Options.OptionsDialogDisplayMode.ConnectionString;
            optionsDialog.ShowDialog(this);

            return !optionsDialog.Cancelled;
        }

        private void ManageDataSources_Load(object sender, EventArgs e)
        {
            // Try until the folder tree list is filled up.
            //  If it's no luck, display the Options dialog.
            //  We let all the other exceptions to crash the process.
            do
            {
                try
                {
                    // Give some time for the framework to write back the config settings to
                    //  the virtual store (seems to be a bug with the framework)
                    Thread.Sleep(2000);

                    // If it's the first start, don't even try to connect by default
                    if (string.Compare(Config.GetConfigValue(Config.PARAM_SQL_SERVER_CONNECTIONSTRING),
                        Config.DEFAULT_SQL_CONNECTIONSTRING, StringComparison.InvariantCulture) != 0)
                    {
                        // Fills up the tree combo
                        FillUpFolderTree();

                        // Exists from the loop if the connection is succeeded
                        break;
                    }
                }
                
                // This is thrown when the connection string is wrong
                //  or SQL doesn't exist
                catch (SqlException)
                {
                    // Lets the user know that there's a problem
                    MessageBox.Show("SQL Server cannot be contacted or permission denied.",
                        "PfRep", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                
                // This is thrown when there's no connection string
                catch (InvalidOperationException)
                {
                }

                // Pops up the Options dialog to set the connection string
                if (!PopupOptionsDialog())
                {
                    UserCancelled = true;
                    break;
                }
                
            } while (true);

            // Close the window if the user has cancelled the connectiong string
            //  setting operation
            if (UserCancelled)
                this.Close();

            // If at least one item in the tree list, we select the 1st one
            if (FolderTrees.Items.Count > 0)
                FolderTrees.SelectedIndex = 0;
        }
    }
}